﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reactive.Joins;

namespace System.Reactive.Linq
{
	public static partial class Qbservable
	{
		public static IQbservable<TSource> Aggregate<TSource>(this IQbservable<TSource> source, Expression<Func<TSource, TSource, TSource>> accumulator)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(accumulator != null, null, "accumulator != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TAccumulate> Aggregate<TSource, TAccumulate>(this IQbservable<TSource> source, TAccumulate seed, Expression<Func<TAccumulate, TSource, TAccumulate>> accumulator)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(accumulator != null, null, "accumulator != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<bool> All<TSource>(this IQbservable<TSource> source, Expression<Func<TSource, bool>> predicate)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(predicate != null, null, "predicate != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Amb<TSource>(this IQbservableProvider provider, params IObservable<TSource>[] sources)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, Qbservable => Qbservable != null), null, "Contract.ForAll(sources, Qbservable => Qbservable != null)");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Amb<TSource>(this IQbservableProvider provider, IEnumerable<IObservable<TSource>> sources)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, Qbservable => Qbservable != null), null, "Contract.ForAll(sources, Qbservable => Qbservable != null)");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Amb<TSource>(this IQbservable<TSource> first, IObservable<TSource> second)
		{
			Contract.Requires(first != null, null, "first != null");
			Contract.Requires(second != null, null, "second != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static QueryablePattern<TLeft, TRight> And<TLeft, TRight>(this IQbservable<TLeft> left, IObservable<TRight> right)
		{
			Contract.Requires(left != null, null, "left != null");
			Contract.Requires(right != null, null, "right != null");
			Contract.Ensures(Contract.Result<QueryablePattern<TLeft, TRight>>() != null, null, "Contract.Result<QueryablePattern<TLeft, TRight>>() != null");
			return null;
		}

		public static IQbservable<bool> Any<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<bool>>() != null, null, "Contract.Result<IQbservable<bool>>() != null");
			return null;
		}

		public static IQbservable<bool> Any<TSource>(this IQbservable<TSource> source, Expression<Func<TSource, bool>> predicate)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(predicate != null, null, "predicate != null");
			Contract.Ensures(Contract.Result<IQbservable<bool>>() != null, null, "Contract.Result<IQbservable<bool>>() != null");
			return null;
		}

		public static IObservable<TSource> AsObservable<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> AsQbservable<TSource>(this IObservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<decimal?> Average(this IQbservable<decimal?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<decimal?>>() != null, null, "Contract.Result<IQbservable<decimal?>>() != null");
			return null;
		}

		public static IQbservable<decimal> Average(this IQbservable<decimal> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<decimal>>() != null, null, "Contract.Result<IQbservable<decimal>>() != null");
			return null;
		}

		public static IQbservable<double?> Average(this IQbservable<double?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double?>>() != null, null, "Contract.Result<IQbservable<double?>>() != null");
			return null;
		}

		public static IQbservable<double> Average(this IQbservable<double> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double>>() != null, null, "Contract.Result<IQbservable<double>>() != null");
			return null;
		}

		public static IQbservable<float?> Average(this IQbservable<float?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<float?>>() != null, null, "Contract.Result<IQbservable<float?>>() != null");
			return null;
		}

		public static IQbservable<float> Average(this IQbservable<float> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<float>>() != null, null, "Contract.Result<IQbservable<float>>() != null");
			return null;
		}

		public static IQbservable<double?> Average(this IQbservable<int?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double?>>() != null, null, "Contract.Result<IQbservable<double?>>() != null");
			return null;
		}

		public static IQbservable<double> Average(this IQbservable<int> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double>>() != null, null, "Contract.Result<IQbservable<double>>() != null");
			return null;
		}

		public static IQbservable<double?> Average(this IQbservable<long?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double?>>() != null, null, "Contract.Result<IQbservable<double?>>() != null");
			return null;
		}

		public static IQbservable<double> Average(this IQbservable<long> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double>>() != null, null, "Contract.Result<IQbservable<double>>() != null");
			return null;
		}
	}
}